package com.jbp.utils.encryptUtils;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;



@Component
public class RsaEncryptUtil {

    private static final Logger logger = LoggerFactory.getLogger(RsaEncryptUtil.class);

    public static String encrypt() {
        return "";
    }

    /**
     * 随机生成密钥对
     * @throws NoSuchAlgorithmException
     */
    public static Map<String, Object> genKeyPair() {
        try {
            final Map<String, Object> keyMap = new HashMap<>();
            // KeyPairGenerator类用于生成公钥和私钥对，基于RSA算法生成对象
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            // 初始化密钥对生成器，密钥大小为96-1024位
            keyPairGen.initialize(1024,new SecureRandom());
            // 生成一个密钥对，保存在keyPair中
            KeyPair keyPair = keyPairGen.generateKeyPair();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥
            String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
            // 得到私钥字符串
            String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
            // 将公钥和私钥保存到Map
            keyMap.put("publicKey",publicKeyString);  //0表示公钥
            keyMap.put("privateKey",privateKeyString);  //1表示私钥
            logger.info("-----publicKey = " + publicKeyString);
            logger.info("-----privateKey = " + privateKeyString);
            return keyMap;
        } catch (NoSuchAlgorithmException e) {
            logger.error("生成RSA密钥对异常", e);
        }
        return null;
    }

    /**
     * 加密
     * @param message 需要加密的字符串
     * @param publicKey 公钥
     * @return
     */
    public static String encrypt(final String message, final String publicKey ) {
        //base64编码的公钥
        try {
            final byte[] decoded = Base64.decodeBase64(publicKey);
            final RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
            //RSA加密
            final Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);

            final byte[] bytes = message.getBytes("UTF-8");
            final int len = bytes.length;//字符串长度
            int offset = 0;//偏移量
            int i = 0;//所分的段数
            final ByteArrayOutputStream bos = new ByteArrayOutputStream();

            while (len > offset) {
                byte[] cache;
                if (len - offset > 117) {
                    cache = cipher.doFinal(bytes, offset, 117);
                } else {
                    cache = cipher.doFinal(bytes, offset, len - offset);
                }
                bos.write(cache);
                i++;
                offset = 117 * i;
            }
            bos.close();

            final String encryptMessage = Base64.encodeBase64String(bos.toByteArray());
            return encryptMessage;
        } catch (InvalidKeyException | InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException
                | IllegalBlockSizeException | BadPaddingException | IOException e) {
            logger.error("使用公钥对数据加密异常", e);
        }
        return null;
    }

    /**
     * 解密
     * @param message 需要解密的密文
     * @param privateKey 私钥
     * @return
     */
    public static String decrypt(String message, final String privateKey) {
        try {
            //logger.info("message1 = " + message);
            if (message.contains(" ")) {
                //logger.info("解码前的字符串包含空格");
                message = message.replaceAll(" ", "+");
            }
            //logger.info("message2 = " + message);
            //base64编码的私钥
            final byte[] decoded = Base64.decodeBase64(privateKey);
            RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            //64位解码加密后的字符串
            final byte[] inputByte = Base64.decodeBase64(message.getBytes("UTF-8"));

            final int len = inputByte.length;//密文
            int offset = 0;//偏移量
            int i = 0;//段数
            final ByteArrayOutputStream bos = new ByteArrayOutputStream();
            while (len - offset > 0) {
                byte[] cache;
                if (len - offset > 128) {
                    cache = cipher.doFinal(inputByte, offset, 128);
                } else {
                    cache = cipher.doFinal(inputByte, offset, len - offset);
                }
                bos.write(cache);
                i++;
                offset = 128 * i;
            }
            bos.close();

            return new String(bos.toByteArray(), "UTF-8");
        } catch (InvalidKeyException | InvalidKeySpecException | NoSuchAlgorithmException
                | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException | IOException e) {
            logger.error("使用私钥对数据解密异常");
        }
        return null;
    }

    public static void main(String[] args) {
//        genKeyPair();
        //String encryptMsg = "T0KMag6KpIBvTMZkP3q/ewfPQrXEDRaBH2IJI1lDgEZjgbhy1QHM94cHXkS4oGqNwVUkgBeomt8DISZyqFVxlLkVla/pxer7Z+yoVehhRAmFH++0ZJf72FNwqIi9DIT4++ngEqFmzbH6c4Pf0D+8tvZ24ZQrzAqXak8sRORNEeU=YWRDfYOi0/sAVa8z6s4U97GaIMPPorvovMn6Pv9aDDy2MGjoGjJP7woRlnHbTE2UF1HyWW7rKzdI2rraqrctiBnjC5Zc6eFo/R2GQc/za/5Dnsyfj3+GspYEAp5+ChYhQp6AzM0NEFCtbgpL4OVE4GDqk/dHCY4HYtxxq+1wrKU=";
        //String pub = "";
        //String pri = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAILBzEP7Wbt1PBiNR9GBvMPv3n63/FzFOj+hk0WUu+H7aQqaSex1edKXHlnG5OCJYVEagUredK3oMqoKFdAMdlqL3XXsp5hGPFptfAithFowT1WGMc1IWbJeE3E2wP9wWuTWVHLIhGBs/lJDcxLrlXAqKrMyNsDSj0Uzh8dxGgrpAgMBAAECgYAEnF7emtNsN9MZrom0ypVkd2XqJATDJLVMHx95WahSbLIkjJJEw1O7aFbKpafWfyGuYXfjsvp8U27N7jMctgPKWniqYaOLvOt7Jk0qFYPD2UxjRsyI87R20yj2VAxBHuQqBU/0neMNSkb37fnw/dsvOvGWlTNSaz0DZgl6CHQMnQJBANy5iBQVwXeTsLRobdsrkZaL5DLwpD0QC1xAosl2xDEA41q86uLsRhQZM8EuGAof3UpJwNAhUn36eUuvjByr6/sCQQCXp29OxjGXP08Fzv4ceMHWG/+mWzhN7Yo/U7Gf2XG7f5Fv2jmYwNks44ugvyr6skTDprtaAfoQ2aCyr8qRretrAkAl+hYbvpKHDHY+1CjyqNBn4rHkwdrAVt5dhRF9MF4ZQFnd5ttTJ+v20U9CUbf5JfphKcdvCAy1eD8ecpnc5Qe5AkAXY0gEMwaU17udHrYLuAfUuE6t3iWJxxdp+sNK7qLekqbgRBxb1WnoxVLUQIclUHbQYZdFI0bocFebFwc7fkHvAkAKbXqMNGhojmfMY4NNUEWhcNlDfTdua9VbrHEjFlxHG2Y0R518pzofgBj0CGWGlHbY6lpaX/IbHzlMFrT92xdi";
        //System.err.println(decrypt(encryptMsg, pri));

        String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCRy6SBFrCyJf2j3V3sB7e1HpxVcpOqOiFIkfJJbfPweItjJ8ccNg3TIiN7dx2NGYfvl2eqzlJsjvN4f5uNuGP9a4hnUoLrCMxsuyoah8GahcjGruPUD4tyrOqoKqEHgzf917K3tHKXRuacW/BDRgp6r/JFcTxnomY9KYCV455R5wIDAQAB";
        String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJHLpIEWsLIl/aPdXewHt7UenFVyk6o6IUiR8klt8/B4i2Mnxxw2DdMiI3t3HY0Zh++XZ6rOUmyO83h/m424Y/1riGdSgusIzGy7KhqHwZqFyMau49QPi3Ks6qgqoQeDN/3Xsre0cpdG5pxb8ENGCnqv8kVxPGeiZj0pgJXjnlHnAgMBAAECgYEAhdTYYgLxGecTyFrI/4QqF2FNAobVk9oeeV43eT4sQZ513QRDmtrnn9rjlU9HWiGIjd9+suUH9kzWo9MHeHU9mpoJf6IuvJYje3+Ec/ydkBZGdsPJnzdMXtrEF5v2SQUGMDbdjH1c9JhPQf/JHXca1VF5ubzSWPkEkJmSYj4heGECQQDd11BQkpXojPgNyKyw/DNUZfc65c49Ti1igovuZNpmS1sOpvxSSxAZmazZcJfAWFBKRaICOKCBmqkmr++PNKrXAkEAqD617SzYW8SJP3Fa1p2WMKxIpCp4Y7Lm2abfFuCgNzjGzGiZnxxorFZZ+I41qOdec7iiKciQocyhgRbsjMw/cQJBAM3cUJt0a8gxiL7Byf8zCi73sETnnEsnkNYpbtD6pfDnXMhsDRoQrhATm2LsKOZFDbzegUiuY8PhUbak7RlnNmECQClWLxC04fu6EBacXTs5wLr4uWhMXwPv4rQ7Qbi3O+YVdxKl6IilTDp7hOOC3UBAiH5aMM2fT5nRUyUKYtg9HqECQGvSyX3qX1z/teNCjawKnfxeH9Xo0M32PmRi5hS80zBvRgQqgfyaocrlvvjiArVBtwne1Eycc4xWBtQAK5DTpTk=";
        String msg = "{\n" +
                "    \"mobile\": \"12327120716\",\n" +
                "    \"password\": \"abc\",\n" +
                "    \"device\": \"B5E92808-42D6-4271-BF78-C57D04522FA5\",\n" +
                "    \"messageCode\": \"abc\",\n" +
                "    \"type\": \"normal\",\n" +
                "    \"aesVipara\": \"abcdabcdabcdabcd\",\n" +
                "    \"aesKey\": \"1234567812345678\"\n" +
                "}";
        /*msg = "{\n" +
                "    \"mobile\":\"18627120716\",\n" +
                "    \"password\":\"a1234567\",\n" +
                "    \"type\":\"pass\",\n" +
                "    \"device\":\"xxdfsfadd\",\n" +
                "    \"aesVipara\": \"abcdabcdabcdabcd\",\n" +
                "    \"aesKey\": \"1234567812345678\"\n" +
                "}";*/
        msg = "123424235346464";
        logger.debug(msg);
        String encryptedData = RsaEncryptUtil.encrypt(msg, publicKey);
        logger.debug(encryptedData);
        System.out.println(encryptedData);

        String enResult = "wr4Zpp+NqayjCbuG6JqSDLFUioDT8HEUNwe6+yDM1GGfwuuDQPvnkPf71JWfm2jX52R/4dgjstFnfQy8jPPajRbxAzyzIJkE69RqO2i4aTYWdn12EOOEhIFH03IDwRnhkt4txRY0S9rYDyQxezD5EvQbVAk4w3pM5VrS3V7gml3QgbHYuggr3vgqWTR0CVaftecl4MWGl43nbM+Sztz6C1gUB+1onzx8KCTC57hlXRGsiW78LEFXUypUlcVAHm16GI2qpj7Ojcwvm5xgms7YajR2lCDsIp1Znifro+x11E/V50TBdGzL1WDi59VoHSWxsvZ712N5hydtmq2Fol0JULQ88jOBPrFeVuELCR7D9vH07C5nkmXgqhAy+6xq8bdEIK4GEodasdHtExvripd+iZo1dUBPZMkRc9ggwbRBYMgX9cbEqyH1CREKxEXvw9u19ftnRgeKtzVS0l10he1bmSm35p/RGXc+PlASqkpFLMXORspSkSygy+Lbvq/kJAd/ZzMpvccZI2qx880RxFlay372sTm0+Ccl7HhRO+J8b3YHfsIw6wWM1n/K8eWDcj1med/W3RtT6TrnsNpWNbZcvlpnaZzgerWkYSb0oXeqiiSuFHS/gq2+T0zd1nwhSJ0FOIqndj+zLFDuW/PSVCH7DHFB6nYyZRhDoTkEHuqsUh/CEiBG+9DORr1lbxC1BCyLV+utTXDKxygtcJ/0EEX3bm45eCBUAauIB/p8M4oGQ1xBoBxy1HKwYbicFNff1sQKR2g7Xg31Jg5iWgLIGPHaNw==";
        String result = AesEncryptUtil.decrypt(enResult,"abcdabcdabcdabcd","1234567812345678");
        logger.debug("reult: "+ result);
    }

}
